home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
DS-CD ROM 2 1993 August
/
DS CD-ROM 2.Ausgabe (August 1993).iso
/
programm
/
ds0334
/
sim51_04.arj
/
OMF51.DOC
< prev
next >
Wrap
Text File
|
1993-02-01
|
18KB
|
487 lines
OMF51 : Intel Objekt-Modul-Format für 8051 Code:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Dieser Text enthät eine Beschreibung des Intel Objekt Modul Formats beim
MCS51-Assembler ASM51, soweit er mir bekannt ist. Der Inhalt ist ohne Ge-
währ für Richtigkeit und Vollständigkeit. Hingegen bin ich für Hinweiße auf
Fehler und Ergänzungen dankbar: Werner Hennig-Roleff, Sulzgrieser Str. 101
73733 Esslingen, 0711/376718.
Laut telefonischer Auskunft von Intel (München) gab es vor Jahren eine Dok-
umentation von Intel zum OMF, jetzt aber nichts mehr. Laut Auskunft von
einem Mitarbeiter von Hitex (entwickelt 8051-Emulatoren) wäre der OMF von
Intel nicht veröffentlicht worden. Sie hätten den Code auch erst selbst ent-
schlüsseln müssen.
Das Objekt-Modul-Format OMF51 wird bei 8051 Entwicklungsumgebungen verwen-
det vom
Assembler (ASM51 von Intel / A51 von Keil) für Objekt-File Output
C-Compiler (C51 von Keil) für Objekt-File Output
Libary Manager (LIB51 von Intel oder Keil) für Libery-File
Linker und Locator (RL51 von Intel / L51 von Keil) für Absolut-File Output
Emulatoren (von Hitex und Intel ICE51)
Simulatoren (natürlich SIM51 !!!)
Objekt- und Libary-Files enthalten Code, der noch keiner festen Codeadresse
zugeordnet sein muß (relocateable Segmente). In Absolut-Files ist jedes
Code-Byte einer festen Adresse zugeordnet. Adressangaben in Absolut-Files
sind absolute Werte. In Objekt- und Libary-Files sind Adressangaben nur
Offsetwerte bezüglich des Segmentstarts.
Ein Absolut- sowie ein Objektfile ist aus einer Aneinanderreihung von Re-
cords definiert. Jedes Record schließt sich direkt an das vorige an. Sie
besitzen folgenden prinzipiellen Aufbau:
┌─────┬──────────┬────────────────────┬─────┐
│ Typ │ Length │ ... body ... │ CHK │
└─────┴──────────┴────────────────────┴─────┘
(Byte) (Word) (n - Bytes) (Byte)
Length gibt die Länge des Records in Bytesanzahl an. Der Wert wird aus
der Bytesanzahl des Record-body's und der Checksumme gebildet
(Length = n+1). An erster Position steht das Low-Byte, danach das
High-Byte. Es können so maximal 0FFFBh Code-Bytes in einen Record ge-
schrieben werden (siehe Typ 06). Programme wie OH.EXE (Absolut- zu
Hex-File Konverter) bearbeiten jedoch nur Records mit bis zu ca. 500h
Code-Bytes.
Der Aufbau des Record-body's ist je nach Record-Typ verschieden.
CHK wird gebildet aus: die Quersumme über alle Bytes des Records außer CHK
selbst. Davon das Zweierkomplement, wobei anschließend das high Byte
vernachlässigt wird. (Zweierkomplement durch NEG AX beim 8086).
Der oben definierte Aufbau eines Records wird bei vielen Compilern zur Er-
stellung von Objekt-Files verwendet. Die Objekt-Files von Compiler für ver-
schiedene CPU's unterscheiden sich im für sie definierten Satz von gültigen
Record-Typen. Im folgenden werden die für den 8051 Assembler und C-Compiler
definierten Record-Typen beschrieben (soweit bekannt und ohne Garantie).
1
** Modul-Start:
---------------
Dieser Record definiert den Modul-Namen und steht am Anfang von Absolut-
und Objekt-Files.
┌────┬────────┬────┬──────────────┬────────┬────┐
│ 02 │ Length │NaL │ .. Name .. │ ? │CHK │
└────┴────────┴────┴──────────────┴────────┴────┘
In NaL steht die Länge des folgenden Namens (Byteanzahl).
In den dem Namen folgenden Word (?) steht meißt
00FF bei einem Absolut-File (RL51-Output) oder
00FD bei einem Objekt-File (ASM51-Output) oder
01FE bei einem C-Compiler-Objekt-File.
** Modul-End:
-------------
Dieser Record steht am Ende von Absolut-, Objekt- und Libary-Files.
┌────┬────────┬────┬──────────────┬────────┬────┬────┬────┐
│ 04 │ Length │NaL │ .. Name .. │ ? │RegB│ ? │CHK │
└────┴────────┴────┴──────────────┴────────┴────┴────┴────┘
In NaL steht die Länge des folgenden Namens (Byteanzahl).
Im Feld RegB sind die verwendeten Register-Banks gekennzeichnet: das lowest
Bit kennzeichnet Registerbank 0 das nächste RegBnk 1, usw. Steht eine 1 in
diesem Bit, so ist die Registerbank selektiert (USING Direktrive).
Beispiel: 0001b selektiert nur RegBnk 0
1001b selektiert RegBnk 0 und 3
In dem mit ? gekennzeichneten BYTE steht meißt 00.
In den dem Namen folgenden WORD steht meißt 0000.
** Hex-Code:
------------
┌────┬────────┬────┬────────┬───────────────┬────┐
│ 06 │ Length │SNr │ Adr │ .... c .... │CHK │
└────┴────────┴────┴────────┴───────────────┴────┘
Im mit ... c ... gekennzeichneten Feld steht der Hex-Code (mehrere Byte).
Im Feld Adr (Word: low Byte zuerst) ist die Adresse des ersten Codebytes in
diesem Record angegeben.
SNr enthält die Segment-Nummer zu dem dieser Code gehört (siehe Typ 0E).
2
** Debug-Info Heater:
---------------------
┌────┬────────┬────┬────┬──────────────┬────┐
│ 10 │ Length │ K │NaL │ .. Name .. │CHK │
└────┴────────┴────┴────┴──────────────┴────┘
War bei der Assemblierung die Option Debug gewählt, so geht jeder Gruppe
von Records ein Heater vorraus. Der Heater gibt den Modul-Namen bekannt, zu
dem die folgenden Records gehören. Beim C51 gibt es auch Heater mit Funk-
tiuonsnamen.
In dem mit K gekennzeichneten Feld steht meißt
00 wenn globale Symbol-Definitionen folgen
03 wenn globaler Code folgt
02 wenn lokale Symbol-Definitionen folgen
05 wenn lokaler Code folgt
Die Unterscheidung in K = 02 oder 05 wurde nur beim C-Compiler beobachtet.
Beim Assembler wurde nur K = 00 oder 03 beobachtet. K = 01 trat nur bei er-
weiterten OMF51 auf.
Üblicherweise hat ein Objekt-File folgenden Aufbau:
02 Modulstart
0E Segmentdefinitionen
18 EXTRN-Definitionen
16 PUBLIC-Definitionen
10 Heater für Symbolnamen
12 Symbolnamen
10 Heater für Code
06 Code
08 Relocation-Informationen
12 Zeilenzuordnungen
04 Modul-Ende
Verschiedene Records können auch mehrfach vorhanden sein. Bei einem
Absolut-File entfallen die Typen 0E, 18, 16, 08. Obwohl Zeilenzuordnungen
vom Typ 12 sind kommen sie unter dem Code-Heater.
** Debug-Info (Symbol-Definition):
----------------------------------
Ein Record kann Definitionen für mehrere Variablen beinhalten. Der mittlere
Teil wiederholt sich dann.
┌────┬────────┬────┐ ┌────┬────┬────────┬────┬────┬──────────────┐
│ 12 │ Length │S/V │ │SNr │ T │ Wert │ ? │NaL │ .. Name .. │
└────┴────────┴────┘ └────┴────┴────────┴────┴────┴──────────────┘
: :
┌────┬────┬────────┬────┬────┬──────────────┐ ┌────┐
│SHr │ T │ Wert │ ? │NaL │ .. Name .. │ │CHK │
└────┴────┴────────┴────┴────┴──────────────┘ └────┘
S/V gibt an, ob die folgende Zuordnung sich auf einen Segmentnamen oder ei-
ne Variable bezieht. Jedem Segmentnamen ist auch ein Wert zugeordnet, näm-
lich der Wert der ersten Variable/Adresse in dem Segment. Achtung: Ist
S/V = 03, so enthält der Record Zeilezuordnungen (siehe unten).
3
S/V = 00 Variablen-Namen folgen
S/V = 01 public deklarierte Variablen-Namen folgen
S/V = 02 Segment-Namen folgen
S/V = 03 Adress-Zeile Zuordnungen folgen
(Achtung! anderer Record-Body!! - siehe unten!)
SNr enthält die Segment-Nummer zu dem dieser Definition gehört (siehe
Typ 0E).
T gibt den Typ an: 00 = CODE
01 = XDATA
02 = DATA
03 = IDATA
04 = BIT
05 = NUMBER (EQU)
Wert (Word: low Byte zuerst) gibt die Adresse der Variablen bzw. den Wert
an. Der Wert ist immer als WORD abgelegt, auch wenn es sich um eine DATA-
Adresse handelt.
** Debug-Info (Zeilenzuordnung):
--------------------------------
┌────┬────────┬────┐ ┌────┬────────┬────────┐
│ 12 │ Length │ 03 │ │SNr │ Adresse│ Zeile │
└────┴────────┴────┘ └────┴────────┴────────┘
: :
┌────┬────────┬────────┐ ┌────┐
│SHr │ Adresse│ Zeile │ │CHK │
└────┴────────┴────────┘ └────┘
SNr enthält die Segment-Nummer zu dem dieser Definition gehört (siehe
Typ 0E).
Adresse und Zeile sind jeweils als WORD abgelegt.
** Segment-Namen:
-----------------
┌────┬────────┐ ┌────┬───┬──────┬──────┬──────┬─────┬────────────┐
│ 0E │ Length │ │ Nr │ T │ ? │Start │ Size │ NaL │ .. Name .. │
└────┴────────┘ └────┴───┴──────┴──────┴──────┴─────┴────────────┘
: :
┌────┬───┬──────┬──────┬──────┬─────┬────────────┐ ┌─────┐
│ Nr │ T │ ? │Start │ Size │ NaL │ .. Name .. │ │ CHK │
└────┴───┴──────┴──────┴──────┴─────┴────────────┘ └─────┘
Nr (Byte) beinhaltet eine laufende Nummer der Segment-Namen Definitionen.
Das erste relocateable Segment erhält die Nummer 1 usw. Alle festen Segmen-
te (CSEG, DSEG, ...) erhalten hier die Nummer 0. Die Anzahl der definierba-
ren relocateablen Segmente ist begrenzt (1 bis 255). Beim Hochzählen wird
nicht nach Typen unterschieden.
4
T (Byte) gibt den Sgment-Typ an: 00 = CODE
01 = XDATA
02 = DATA
03 = IDATA
04 = BIT
Start (WORD) gibt die Adresse des ersten Eintrags in dieses Segments an.
Bei relocatablen Segmenten ist dies ein Offset-Wert (= 0000, denn jedes Re-
locateable Segment beginnt mit Offset 0000).
Size (WORD) gibt die Anzahl der in diesem Segment enthaltenen Bytes an.
Bei festen Segmenten ist die Namenlänge (NaL) 0.
In den mit ? (WORD) markierten Feld steht meißt
0000 bei festen Segmenten
0001 bei relocateablen Segmenten
** EXTRN Deklaration:
---------------------
┌────┬────────┐ ┌───┬────┬───┬───┬─────┬────────────┐
│ 18 │ Length │ │ ? │ Nr │ T │ ? │ NaL │ .. Name .. │
└────┴────────┘ └───┴────┴───┴───┴─────┴────────────┘
: :
┌───┬────┬───┬───┬─────┬────────────┐ ┌─────┐
│ ? │ Nr │ T │ ? │ NaL │ .. Name .. │ │ CHK │
└───┴────┴───┴───┴─────┴────────────┘ └─────┘
In dem ersten mit ? markierten Feld (BYTE) steht meißt 02
In den zweiten mit ? markierten Feld (BYTE) steht meißt 00
Nr (Byte) beinhaltet eine laufende Nummer der EXTRN-Deklarationen (anstei-
gend von 00 bis FF).
T (Byte) gibt den Variablen-Typ an: 00 = CODE
01 = XDATA
02 = DATA
03 = IDATA
04 = BIT
05 = NUMBER
EXTRN-Deklarationen kommen in Absolut-Files nicht vor.
5
** PUBLIC-Deklarationen:
------------------------
┌────┬────────┐ ┌────┬───┬──────┬───┬─────┬────────────┐
│ 16 │ Length │ │SNr │ T │ Wert │ ? │ NaL │ .. Name .. │
└────┴────────┘ └────┴───┴──────┴───┴─────┴────────────┘
: :
┌────┬───┬──────┬───┬─────┬────────────┐ ┌─────┐
│SNr │ T │ Wert │ ? │ NaL │ .. Name .. │ │ CHK │
└────┴───┴──────┴───┴─────┴────────────┘ └─────┘
In dem mit ? markierten Feld (BYTE) steht meißt 00
SNr (Byte) beinhaltet die Nummer des Segments in dem der PUBLIC zu deklara-
rierende Wert steht (siehe Typ 0E).
T (Byte) gibt den Variablen-Typ an: 00 = CODE
01 = XDATA
02 = DATA
03 = IDATA
04 = BIT
05 = NUMBER
Der Wert ist immer als WORD abgelegt, auch wenn es sich um eine DATA-
Adresse handelt.
PUBLIC-Deklarationen kommen in Absolut-Files nicht vor.
** Relocate-Information:
------------------------
Dieser Record folgt unmittelbar einem Record in dem Sprünge in ein reloca-
teables Segment enthalten sind.
┌────┬────────┐ ┌────────┬────┬────┬────┬────────┐
│ 08 │ Length │ │ QAdr │ ? │ X │SNr │ ZAdr │
└────┴────────┘ └────────┴────┴────┴────┴────────┘
: :
┌────────┬────┬────┬────┬────────┐ ┌─────┐
│ QAdr │ ? │ X │SNr │ ZAdr │ │ CHK │
└────────┴────┴────┴────┴────────┘ └─────┘
X enthält den Wert 01, wenn sich die Zieladresse in diesem Modul befindet.
Dabei gilt:
ZAdr (WORD) definiert einen Offset im Ziel-Segment.
SNr enthält die Nummer des Ziel-Segments.
QAdr hält den Offset in diesem Segment, an den der Linker die absolute
Zieladresse eintragen soll. Dabei kann es sich um Adressen bzw. Werte
beliebigen Typs handeln.
X enthält den Wert 02, wenn sich die Zieladresse in einem anderen Modul be-
findet. Die Zieladresse ist dann extrn definiert (siehe Typ 18). Dabei
gilt:
SNr hält die Nummer der EXTRN-Deklaration im Record-Typ 18, die die
Ziel-Adresse bezeichnet. Im Feld ZAdr steht hier meißt 0000.
6
In dem mit ? bezeichneten Feld steht meist
04 beim Typ CODE, XDATA, NUMBER (16 Bit)
01 beim Typ DATA, IDATA, NUMBER (8 Bit)
06 beim Typ BIT
Relocate-Informationen kommen in Absolut-Files nicht vor.
Beim erweiterten OMF51 sind noch zusätzliche Record-Typen definiert:
====================================================================
Erweitertes OMF51 wird verwendet beim C51 Compiler, wenn das Controlwort
OBVJECTEXTEND im C-Sourcefile angegeben wude (#pragma OE)
Typ 24 hierin wird offenbar der Name des Sourcefiles abgelegt. Diesen
Typ trägt schon der C51-Compiler ein. Der Linker übernimmt den
Record nur in den Absolut-File. In einem Absolut-File können so
mehrere Records vom Typ 24 enthalten sein.
┌────┬────────┬────┬────┬────┬────┬──────────────┬────┐
│ 24 │ Length │ ? │ ? │ ? │NaL │ .. Name .. │CHK │
└────┴────────┴────┴────┴────┴────┴──────────────┴────┘
In NaL steht die Länge des folgenden File-Namens (Byteanzahl).
Typ 22 diser Typ ersetzt Typ 12 bei den Symboldefinitionen und ist
ähnlich aufgebaut. Beim C51-Compiler sind offenbar die Funk-
tionen in Libary-Files nicht mit OBJECTEXTEND compiliert,
so daß Symbole aus dazugelinkten Libarys weiterhin mit Typ 12
definiert sind.
dazu ist nebenbei noch zu bemerken, daß vom C51-Compiler Funktionen
und globale Variablen PUBLIC deklariert werden. Variablen, die inner-
halb von Funktionen definiert wurden, erhalten kein PUBLIC-Attribut.
Variablen, die innerhalb von Unterfunktionen (alle anderen außer main)
definiert wurden, werden außerdem vom Linker überlagert.
Typ 20 ??? hier werden offenbar Übergabeparameter für Funktionen
definiert. ???
7
Record-Typen beim Libary-Manager LIB51.EXE:
===========================================
Der Libary-Manager LIB51.EXE bindet alle Records eines Moduls (inclusive
Start- und End-Record Typ 02 und 04) in der Reihenfolge, wie sie im
Objekt-File stehen, in den Libary-File ein.
Am Beginn eines Libary-Files steht folgender Record:
┌────┬────────┬────────┬────┬────┬────┬────┬────┐
│ 2C │ Length │ ModCnt │ ? │ ? │ ? │ ? │CHK │
└────┴────────┴────────┴────┴────┴────┴────┴────┘
ModCnt (WORD) hält die Anzahl der Module, die ADDed sind.
Nach diesem Libary-Start-Record folgen die einzelnen Module hintereinander.
Hinter den Records der Module kommen noch folgende Records:
** Modul-List:
--------------
┌────┬────────┐ ┌────┬──────────────┐
│ 28 │ Length │ │NaL │ .. Name .. │
└────┴────────┘ └────┴──────────────┘
: :
┌────┬──────────────┐ ┌────┐
│NaL │ .. Name .. │ │CHK │
└────┴──────────────┘ └────┘
Hier werden sämtliche Modul-Namen aufgelistet (keine Zuordnung).
** ????
--------
┌────┬────────┐ ┌────┬────┬────┬────┐
│ 26 │ Length │ │ ? │ ? │ ? │ ? │
└────┴────────┘ └────┴────┴────┴────┘
: :
┌────┬────┬────┬────┐ ┌────┐
│ ? │ ? │ ? │ ? │ │CHK │
└────┴────┴────┴────┘ └────┘
Wahrscheinlich eine Liste der Offsetadressen der einzelnen Module innerhalb
des Libary-Files (dieselbe Reihenfolge wie bei Typ 28 ?).
** Public-List:
---------------
┌────┬────────┐ ┌────┬──────────────┬────┐
│ 2A │ Length │ │NaL │ .. Name .. │ ? │
└────┴────────┘ └────┴──────────────┴────┘
: :
┌────┬──────────────┬────┐ ┌────┐
│NaL │ .. Name .. │ ? │ │CHK │
└────┴──────────────┴────┘ └────┘
Liste alle Publics aus allen Modulen
8